using System;
using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Collections;
using System.Collections.Generic;

//using IBM.Data.DB2;
using Novell.Directory.Ldap;
using ldapAccountGen;

namespace ldapAccountGen
{
    class SController
    {
        private Properties.Settings settings = Properties.Settings.Default;

        public SController()
        {
        }
        public void create(Logger log)
        {
            int cnt = 0; int cntA = 0; int cntU = 0; int cntM = 0; int rcnt = 0;
            try
            {
                // Get the colleges from the app.config file.
                Colleges colleges = new Colleges();
                
                // Now let's get started on the student accounts.                        
                log.write("Registering Students...", "APPEND");
                
                // Let's read in the students from a) file b) DB2 directly c) MSSQL Server
                // Option b)
                //DBAdapter da = new DBAdapter("DB2");
                // Option c)
                DBAdapter da = new DBAdapter("MS");
                try
                {
                    SqlCommand cmd = da.msCommandDB();
                    SqlDataReader dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                        cnt++;
                        string pwd = System.Convert.ToString(dr["BIRTHDATE"]);
                        pwd = pwd.Substring(4, 4) + pwd.Substring(0, 4);

                        User student = new User();
                        student.cn = System.Convert.ToString(dr["USERNAME"]).Trim();
                        student.sn = System.Convert.ToString(dr["LASTNAME"]).Trim();
                        student.gn = System.Convert.ToString(dr["FIRSTNAME"]).Trim();
                        student.fullName = student.gn + " " + student.sn;
                        student.password = pwd;
                        student.college = System.Convert.ToString(dr["PRIMPGMCOLLEGE"]).Trim();
                        student.email = System.Convert.ToString(dr["EMAIL"]).Trim();
                        student.major = System.Convert.ToString(dr["PRIMACADPGM"]).Trim();
                        student.area = System.Convert.ToString(dr["PRIMPGMAREACODE"]).Trim();
                        student.parentDn = "ou=" + settings.PARENT + ",o=" + settings.ORG;

                        if (student.college == "32")
                        {
                            //ADAdapter adAdap = new ADAdapter();
                        }

                        LDAPUser lUser = new LDAPUser();
                        //log.write("Processing user: " + student.cn, "APPEND");
                        // Build the table of properties this user account has set
                        Hashtable ut = lUser.UserTable(student.cn, "cn", "ou=Student");
                        if (ut.Count == 0)
                        {
                            string ret = "";
                            // Create account.
                            ret = lUser.createAccount(student);
                            if (ret != "")
                            {
                                log.write(ret, "ERROR");
                            }
                            else
                            {
                                cntA++;
                                log.write("Added: " + student.cn,"APPEND");
                            }
                        }
                        else
                        {
                            string ret = "";
                            System.Collections.ICollection keys = ut.Keys;
                            foreach (string key in keys)
                            {
                                // Check user properties                                
                                student.checkProps(ut, key);

                                // Modify account.
                                string[] userAcc = (string[])ut[key];
                                ret = lUser.setDefaults(student, userAcc, 12);
                                if (ret != "")
                                {
                                    log.write(ret, "ERROR");
                                }
                                else
                                {
                                    cntU++;
                                }

                                // Move user to new dn
                                if (student.newDn != null)
                                {
                                    //lUser.moveUser(student);
                                    cntM++;
                                }                                
                            }
                        }
                        // Now we create thier AD account if CAS student
                        
                        // Lets display a running count.
                        rcnt++;
                        if (rcnt == 1000)
                        {
                            rcnt = 0;
                            Console.WriteLine(cnt.ToString());
                        }
                    }
                }
                catch (Exception exp)
                {                   
                    log.write("Error: " + exp.Message, "ERROR");
                }
                finally
                {
                    da.msClose();
                    log.write("============================================================", "APPEND");
                    log.write("Added: " + cntA.ToString() + " Updated: " + cntU.ToString() + " Moved: " + cntM.ToString(), "APPEND");
                    log.write("============================================================", "APPEND");
                    log.write("Processed: "+ cnt.ToString() +" accounts.", "APPEND");
                }
            }
            catch (Exception exp)
            {
                log.write("Error: " + exp.Message, "ERROR");
                //argIn = Console.ReadLine();
                return;
            }
        }
        public void dump(Logger log)
        {
            LDAPUser lUser = new LDAPUser();
            int cnt = 0;
            // Option a) Dump to file b) Dump to DB table
            // a)
            StreamWriter sw = new StreamWriter(@"C:\temp\logs\UserDump.txt");
            sw.WriteLine("Username:Last Name:First Name:College:Full User DN:Expiration:OldExpiration");
            // b)
            // First let's get the data from the DB2 database.
            //DBAdapter da = new DBAdapter("DB2");
            //DBAdapter mda = new DBAdapter("MS");
            // Now let's drop the data in the UserAccounts table.
            try
            {
                string[] letters = new string[26] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };

                Colleges college = new Colleges();
                System.Collections.ICollection OUs = college.getValues();
                try
                {
                    foreach (string ou in OUs)
                    {
                        foreach (string let in letters)
                        {                            
                            Hashtable ut = lUser.UserTable(let+"*", "cn", "ou="+ ou +",ou=Student");
                            System.Collections.ICollection keys = ut.Keys;
                            foreach (string key in keys)
                            {
                                cnt++;
                                string[] row = (string[])ut[key];
                                sw.WriteLine(row[0] + ":" + row[1] + ":" + row[3] + ":" + row[2] + ":" + key + ":" + row[7] + ":" + row[4]);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            catch (Exception e)
            {                
                throw e;
            }
            finally
            {
                sw.Close();
                log.write("============================================================", "APPEND");
                log.write("Dumped: " + cnt.ToString() + " accounts.", "APPEND");
            }
        }
        public void remove(Logger log)
        {
            LDAPUser lUser = new LDAPUser();
            int cnt = 0;

            //log.write("Removing Temp Accounts....", "APPEND");
            //log.write("============================================================", "APPEND");

            log.write("Removing Expired Accounts....", "APPEND");
            log.write("============================================================", "APPEND");
            
            try
            {
                // Create an instance of StreamReader to read from a file.
                // The using statement also closes the StreamReader.
                using (StreamReader sr = new StreamReader(@"C:\temp\logs\UserDump.txt"))
                {
                    String line;
                    // Read and display lines from the file until the end of the file is reached.
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line != "Username:Last Name:First Name:College:Full User DN:Expiration:OldExpiration")
                        {
                            string[] sline = line.Split(':');
                            if (sline[5] == "" || sline[5] == "")
                            {
                                cnt++;
                                // Remove the accounts but also log it just in case.
                                if (lUser.removeAccount(sline[4]) == "")
                                {
                                    log.write(sline[4], "APPEND");
                                }
                                else
                                {
                                    log.write("Account doesn't exists: " + sline[4], "ERROR");
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.write(e.Message, "ERROR");
            }
            finally
            {
                log.write("============================================================", "APPEND");
                log.write("Removed: "+ cnt.ToString() + " accounts.", "APPEND");
            }
        }
    }    
}

// #########################################################################
// #########################################################################
// Old code to dump accounts to somewhere directly from DB2
// #########################################################################
// #########################################################################
//log.write("Cleaning UserAccounts Table...", "APPEND");
//
//
//log.write("Populating UserAccounts Table...", "APPEND");
// Let's do the Student Accounts now.
//
//log.write("Student accounts:", "APPEND");
//try
//{
//    DB2Command cmd = da.CommandDB(college[1].ToString());
//    //DataSet dset = da.FillDS(cmd);
//    DB2DataReader dr = cmd.ExecuteReader();
//    while (dr.Read())
//    {
//        string pwd = System.Convert.ToString(dr["BIRTHDATE"]);
//        pwd = pwd.Substring(4,4) + pwd.Substring(0, 4);
//        User student = new User();
//        student.cn = System.Convert.ToString(dr["USERNAME"]);
//        student.sn = System.Convert.ToString(dr["LASTNAME"]);
//        student.gn = System.Convert.ToString(dr["FIRSTNAME"]);
//        student.password = pwd;
//        student.college = System.Convert.ToString(dr["PRIMPGMCOLLEGE"]);
//        student.email = System.Convert.ToString(dr["EMAIL"]);
//        student.major = System.Convert.ToString(dr["PRIMACADPGM"]);
//        student.area = System.Convert.ToString(dr["PRIMPGMAREACODE"]);
//        LDAPUser lUser = new LDAPUser();
//        lUser.UserTable(student.cn, "cn", "ou=Student");
//    }
//}
//catch (DataException dexp)
//{
//    Console.WriteLine(dexp.ToString());
//}
//catch (Exception exp)
//{
//    Console.WriteLine(exp.ToString());
//}
//finally
//{
//    da.Close();                                
//}
//
// Let's do the Faculty Accounts now.
//log.write("Faculty Accounts...", "APPEND");
//
// Let's do the LA Accounts now.
//log.write("LA Accounts...", "APPEND");
//
//log.write("LA accounts:", "APPEND");
// #########################################################################
//log.write("Could not clean UserAccount Table: " + e.Message, "ERROR");
// #########################################################################
//da.Close();
//mda.Close();